﻿using Iworld.Author.Manager;
using Iworld.Author.Model;
 
using Iworld.Author.Service.Backstage.Import;
using Iworld.Author.Service.Client;
using Iworld.Author.Service.Client.Export;
using Iworld.Author.Service.Client.Import;
using Iworld.basis.Service;
using Iworld.Basis.Help;
using Iworld.Basis.Manager;
using Iworld.Game.Manager;
using Iworld.Game.Model;
using Iworld.Game.Service.Client;
using Iworld.Game.Service.Client.Export;
using Iworld.Game.Service.Client.Import;
using Iworld.Main.Impl;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Migrations;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Transactions;


namespace Test
{
    /// <summary>
    /// 声明结果
    /// </summary>
    public static class Assert
    {
        public static void NotNull(object obj,string msg = null)
        {
            if(obj == null)
            {
                throw new Exception(msg == null ? "不能为空" : msg);
            }
        }

        public static void Equals(object obj1,object obj2,string msg = null)
        {
            if (obj1 == obj2) return;
            if (obj1 != null && obj1.Equals(obj2))
            {
                return;
            }
            throw new Exception(msg == null ? "必须相等" : msg);
        }

        public static void True(bool? b, string msg = null)
        {
            if (b == true) return;
            throw new Exception(msg == null ? "必须为真" : msg);
        }

        public static void False(bool? b, string msg = null)
        {
            if (b == false) return;
            throw new Exception(msg == null ? "必须为家" : msg);
        }

    }

    
    /// <summary>
    /// 单元测试类
    /// </summary>
    public class Program 
    {

        static void InDb(Action<ModelToDbContext> fn)
        {
            using (ModelToDbContext db = new ModelToDbContext())
            {
                fn(db);
            }
        }

        static void TestKeepHeartbeat(string[] tks)
        {
            System.Timers.Timer timer = new System.Timers.Timer(20000);
            timer.Elapsed += (sender,args) => {
              //  Logger.Debug("保持心跳中....");
                tks.ToList().ForEach(x =>
                {
                    AuthorLoginInfoPond.KeepHeartbeat(x);
                });
            };
            timer.Start();
        }

        
        static void Test()
        { 
            //初始化信使
            ManagerService.Initialize(new List<Assembly>() { new RIOfAuthor().GetAssembly() ,new RIOfGame().GetAssembly()});

            //用户服务
            AuthorService serv = new AuthorService();

            InDb(db => {
                if (db.Database.Exists())
                {
                    db.Database.Delete();
                }
                Iworld.Administrator.Model.AdministratorGroup g = new Iworld.Administrator.Model.AdministratorGroup() { Name = "超级管理员" };
                Iworld.Administrator.Model.Administrator administrator =
                       new Iworld.Administrator.Model.Administrator()
                       {
                           Account = "admin",
                           Password = EncryptHelper.EncryptByMd5("admin"),
                           Username = "超级管理员",
                           Group=g
                       };
                db.Administrators.Add(administrator);
                db.SaveChanges();
                new SettingOfGame(db){ EachChapterTimeSpan=15, EachRoundTimeSpan=30, LimitRedGolds=10000 }.Save(db);
                new TimelineManager(db,()=>{return new ModelToDbContext();}).Initialize();
            });

            //测试注册
            NormalResult resultForRegister = null;
            string[] accountArr = new string[] { "test", "test1", "test2","aaa","bbb","ccc","ddd","eee" };
            accountArr.ToList().ForEach(x =>
            {
                resultForRegister = serv.Register(new RegisterImport()
                {
                    Account = x,
                    Password = x,
                    TwoLevelPassword = x,
                    QQ = x,
                    IdentityCard = x,
                    Phone = x,
                    Username = x
                });
                Assert.True(resultForRegister.Success, resultForRegister.Error);
            });
        
            //测试账号重复情况
            resultForRegister = serv.Register(new RegisterImport()
            {
                Account = "test",
                Password = "test",
                TwoLevelPassword = "test",
                QQ = "test",
                IdentityCard = "test",
                Phone = "test",
                Username = "test"
            });
            Assert.False(resultForRegister.Success, resultForRegister.Error);

            //测试登录
            NormalResult<string> resultForLogin = serv.Login(new LoginImport() { Account = accountArr[0], Password = accountArr[0] });
            Assert.True(resultForLogin.Success, resultForLogin.Error);
            string tk = resultForLogin.Info;

            resultForLogin = serv.Login(new LoginImport() { Account = accountArr[1], Password = accountArr[1] });
            Assert.True(resultForLogin.Success, resultForLogin.Error);
            string tk1 = resultForLogin.Info;

            resultForLogin = serv.Login(new LoginImport() { Account = accountArr[2], Password = accountArr[2] });
            Assert.True(resultForLogin.Success, resultForLogin.Error);
            string tk2 = resultForLogin.Info;

            ///保持心跳
            TestKeepHeartbeat(new string[]{tk,tk1,tk2});

            //测试登录失败
            resultForLogin = serv.Login(new LoginImport() { Account = accountArr[0], Password = "wrong" });
            Assert.False(resultForLogin.Success, resultForLogin.Error);

            ///测试获取自身的信息
            NormalResult<AuthorExport> resultForGetUserSelfInfo = serv.GetUserSelfInfo(new GetUserSelfInfoImport() { Token = tk });
            Assert.Equals(resultForGetUserSelfInfo.Info.Account, accountArr[0]);
            AuthorExport ae = resultForGetUserSelfInfo.Info;

            resultForGetUserSelfInfo = serv.GetUserSelfInfo(new GetUserSelfInfoImport() { Token = tk1 });
            Assert.Equals(resultForGetUserSelfInfo.Info.Account, accountArr[1]);
            AuthorExport ae1 = resultForGetUserSelfInfo.Info;

            resultForGetUserSelfInfo = serv.GetUserSelfInfo(new GetUserSelfInfoImport() { Token = tk2 });
            Assert.Equals(resultForGetUserSelfInfo.Info.Account, accountArr[2]);
            AuthorExport ae2 = resultForGetUserSelfInfo.Info;
          
            //测试修改基本信息
            NormalResult resultForEditBaseInfo = serv.EditBaseInfo(new EditAuthorBaseInfoImport()
            {
                TwoLevelPassword = accountArr[0],
                QQ = "新的QQ"
            , Username="新的名称", Phone="新的电话", Token=tk
            });
            Assert.True(resultForEditBaseInfo.Success, resultForEditBaseInfo.Error);

            InDb(db =>
            {
                Assert.True(db.Authors.FirstOrDefault(x => x.Account == "test").Username == "新的名称", "修改基本信息错误");
            });

            resultForEditBaseInfo = serv.EditBaseInfo(new EditAuthorBaseInfoImport()
            {
                TwoLevelPassword = accountArr[0],
                QQ = accountArr[0],
                Username = accountArr[0],
                Phone = accountArr[0],
                Token = tk
            });
            Assert.True(resultForEditBaseInfo.Success, resultForEditBaseInfo.Error);

             ///生成充值卡
             InDb(db =>
             {
                 RechargeCardManager rcm = new RechargeCardManager(db);
                 rcm.Generate(new Generate() { Golds = 100000 });
             });

             ///测试充值
             RechargeCard card = null;
             InDb(db =>
             {
                 card = db.RechargeCards.Take(1).ToList()[0];
             });
             NormalResult resForRecharge = serv.Recharge(new RechargeImport() { Token = tk, Account = card.Account, Password = card.Password });
             Assert.True(resForRecharge.Success, "充值失败:" + resForRecharge.Error);

             ///充值记录
             GetRechargeRecordsImport gr = new GetRechargeRecordsImport() { Token = tk};
             PageResult<RechargeRecordExport> prForRechargeRecord = serv.GetRechargeRecords(gr);
             Assert.True(prForRechargeRecord.Success, "充值记录查询失败");

             ///赠送金币
             NormalResult resultForGiveGolds = serv.GiveGolds(new GiveGoldsImport() {
                 Token = tk,
                 Account = accountArr[1],
                 Golds = 30000,
                 TwoLevelPassword = accountArr[0]
             });
             Assert.True(resultForGiveGolds.Success, "赠送金币失败:" + resultForGiveGolds.Error);

             resultForGiveGolds = serv.GiveGolds(new GiveGoldsImport()
             {
                 Token = tk,
                 Account = accountArr[2],
                 Golds = 30000,
                 TwoLevelPassword = accountArr[0]
             });
             Assert.True(resultForGiveGolds.Success, "赠送金币失败:"+resultForGiveGolds.Error);

             string a2 = accountArr[2];
             string a1 = accountArr[1];
             string a = accountArr[0];
             InDb(db =>
             {
                 Assert.True(db.Authors.FirstOrDefault(x => x.Account == a2).Golds == 30000, a2 + "收到赠送金币不对");
                 Assert.True(db.Authors.FirstOrDefault(x => x.Account == a1).Golds == 30000, a1 + "收到赠送金币不对");
                 Assert.True(db.Authors.FirstOrDefault(x => x.Account == a).Golds == 40000,a+ "赠送金币后余额不对");
             });

             //测试投注
             /*new BettingMan() { TimeSpan = 3000, User = ae, Tk=tk }.Bet(0, 500, 0, 0, 0);
             new BettingMan() {TimeSpan = 4000 ,User = ae1, Tk=tk1}.Bet(0,300,0,0,0);
             new BettingMan() {TimeSpan = 10000, User = ae2,Tk=tk2 }.Bet(0, 0, 200, 300, 0);*/
        }

        class BettingMan
        {

            public string Tk { set; get; }

            public double TimeSpan { set; get; }

            public AuthorExport User { set; get; }

            BettingImport bettingImport;

            int? k = -1;

            public void Bet(double a,double b,double c,double d,double e) 
            {
                System.Timers.Timer timer = new System.Timers.Timer(TimeSpan);
                timer.Elapsed += (sender, args) =>
                {
                    GameService gs = new GameService();
                    NormalResult<GameChapterExport> res = gs.GetCurrentGameInfo(new GetCurrentGameInfoImport() {Token = Tk });
                    GameChapterExport info = res.Info;
                    if(info != null)
                    {
                        if (bettingImport == null)
                        {
                            bettingImport = new BettingImport() { Token = Tk};
                        }
                        if (k != info.NextRoundNumber)
                        {
                            k = info.NextRoundNumber;
                            bettingImport.Spade = 0;
                            bettingImport.Heart = 0;
                            bettingImport.Club = 0;
                            bettingImport.Diamond = 0;
                            bettingImport.King = 0;
                        }
                        bettingImport.GameRoundNum = (int)info.NextRoundNumber;
                        bettingImport.Spade += a;
                        bettingImport.Heart += b;
                        bettingImport.Club += c;
                        bettingImport.Diamond += d;
                        bettingImport.King += e;
                        NormalResult r = gs.Betting(bettingImport);
                        if(r.Success)
                        {

                        }else
                        {
                            Logger.Debug("投注错误:"+r.Error);
                        }
                      }
                  
                };
                timer.Start();
            }
        }


        class Generate :Iworld.Author.Manager.RechargeCardManager.IPackageForGenerate
        {
            public double Golds { set; get; }
     
        
                public int AdministratorId
                {
	                get { return 1; }
                }
         }

        static void Main(string[] args)
        {
            try
            {
                string a = Guid.NewGuid().ToString();
                string b = Guid.NewGuid().ToString();
                Logger.Info(a+"\r\n"+b); 
               Logger.Info("所有测试已经通过=========================="); 
              //  IEnumerable<string> sd;
 
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
            }

            ConsoleKeyInfo key = Console.ReadKey();
            while(key.Key != ConsoleKey.Escape)
            {
                key = Console.ReadKey();
            }
        }
    }
 
        public class M :Iworld.Author.Manager.RechargeCardManager.IPackageForGenerate
        {

            public double Golds
            {
                get { return 1000; }
            }

            public int AdministratorId
            {
                get { return 1; }
            }
        }

    public class R : IPackageForRemoveModel<IModelToDbContextOfAuthor>
    {

        public int Id
        {
            get {return 1; }
        }

        public void CheckData(IModelToDbContextOfAuthor db)
        {
          
        }
    }
}
